﻿using System;
using System.Collections.Generic;
using SQLDeploy.Data.Connections;
using System.Collections.ObjectModel;
using SQLDeploy.Data.Internal;
using System.Xml.Serialization;
using System.IO;
using SQLDeploy.Data.Storage.Xml;

namespace SQLDeploy.Data.Environments
{
    [XmlRoot("Environment")]
    [Serializable()]
    public class Environment : NotifyPropertyChanged, IComparable
    {
        private string _name;
        private bool _isReplicated = false;
        private ObservableCollection<_BaseConnection> _connections = new ObservableCollection<_BaseConnection>();

        [XmlAttribute]
        public string Name
        {
            get { return _name; }
            set
            {
                if (value == null)
                    throw new ArgumentNullException("Name cannot be null");
                if (_name == null || !value.Equals(_name, StringComparison.OrdinalIgnoreCase))
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        [XmlAttribute]
        public bool IsReplicated
        {
            get { return _isReplicated; }
            set
            {
                if (_isReplicated != value)
                {
                    _isReplicated = value;
                    OnPropertyChanged("IsReplicated");
                }
            }
        }

        [XmlArray("Connections")]
        [XmlArrayItem("Connection", Type = typeof(ConnectionXmlSerializer<_BaseConnection>))]
        public ObservableCollection<_BaseConnection> Connections
        {
            get { return _connections; }
            set {
                _connections = value;
                OnPropertyChanged("Connections");
            }
        }

        protected List<string> getDistinctConnectionNames()
        {
            List<string> names = new List<string>();
            foreach(_BaseConnection item in Connections)
            {
                if (names.Contains(item.Name.ToLower()))
                    names.Add(item.Name.ToLower());
            }
            return names;
        }

        public List<_BaseConnection> getConnectionsByName(String name)
        {
            List<_BaseConnection> ret = new List<_BaseConnection>();
            foreach (_BaseConnection con in Connections)
            {
                if (Internal.Shared.DefaultStringComparer().Equals(name, con.Name))
                    ret.Add(con);
            }
            return ret;
        }

        //public override bool Equals(object obj)
        //{
        //    return base.Equals(obj);
        //    if (obj == null)
        //        return false;
        //    if (!(obj is Environment))
        //        return false;
        //    int compare = CompareTo(obj);
        //    if (compare == 0)
        //    {
        //        //Names match so check the internal settings.
        //        Environment other = (Environment)obj;
        //        if (other.Connections.Count == Connections.Count)
        //        {
        //            List<string> distinctNames = this.getDistinctConnectionNames();
        //            foreach (string name in distinctNames)
        //            {
        //                if (other.getDistinctConnectionNames().Contains(name))
        //                {
        //                    List<_BaseConnection> myConnections = this.getConnectionsByName(name);
        //                    List<_BaseConnection> otherConnections = other.getConnectionsByName(name);
        //                    if (myConnections.Count != otherConnections.Count)
        //                        return false;

        //                    bool matchFound = false;
        //                    foreach (_BaseConnection myCon in myConnections)
        //                    {
        //                        foreach (_BaseConnection otherCon in otherConnections)
        //                        {
        //                            if (myCon.Equals(otherCon))
        //                            {
        //                                matchFound = true;
        //                                break;
        //                            }
        //                        }
        //                        if (!matchFound)
        //                            return false;

        //                    }
        //                    return true;
        //                }
        //            }
        //        }
        //    }
        //    return false;
        //}

        //public override int GetHashCode()
        //{
        //    //return base.GetHashCode();
        //    return Name.ToLower().GetHashCode();// +getDistinctConnectionNames().GetHashCode();
        //}

        public int CompareTo(object obj)
        {
            if (!(obj is Environment))
                throw new ArgumentException("obj is not an instance of Environment.");
            return Internal.Shared.DefaultStringComparer().Compare(this.Name, ((Environment)obj).Name);
        }

        //public void SaveToFile(string filename)
        //{
        //    using (StreamWriter writer = new StreamWriter(filename, false))
        //    {
        //        XmlSerializer mySerializer  = new XmlSerializer(typeof(Environment));
        //        mySerializer.Serialize(writer, this);
        //    }
        //}

        //public static Environment LoadFromeFile(string filename)
        //{
        //    XmlSerializer serializer = new XmlSerializer(typeof(Environment));
        //    StreamReader reader = new StreamReader(filename);
        //    Environment env = (Environment)serializer.Deserialize(reader);
        //    reader.Close();
        //    return env;
        //}

        //public static void SaveToFile(string filename, Environment obj)
        //{
        //    obj.SaveToFile(filename);
        //}

    }
}
